<template>
    <div class="courseHomeView">
        <!-- 标签筛选区 -->
        <div class="filterSection" style="margin-top: 20px;">
            <CourTypeLabelBox @updateData="updateData" />
        </div>
        <!-- 课程列表 -->
        <div class="courseList">
            <div class="courseGrid" v-if="courses.list.length > 0">
                <CourseCard v-for="course in courses.list" class="courseCard"
                    :key="course.courseId" :courseId="course.courseId" :searchStr="typeLabelBox?.courseName" :searchParticiple="searchParticiple" detailsUrl="/course/courseDetails"
                    @deleteEvent="(courseId)=>{ console.log('删除事件：' + courseId) }"
                    @editEvent="(courseId)=>{ console.log('编辑事件：' + courseId) }"
                    :editMode="false"
                    @collectEvent="(courseId)=>{ console.log('收藏事件：' + courseId) }"
                    :boxWidth="290" />
            </div>
            <div class="empty" v-if="courses.list.length === 0 && courses.pageNum > 0 && !isLoading">未&nbsp;&nbsp;找&nbsp;&nbsp;到&nbsp;&nbsp;相&nbsp;&nbsp;应&nbsp;&nbsp;课&nbsp;&nbsp;程</div>
            <div class="empty miniFont" ref="loadingDom" @click="getCourseList(typeLabelBox, false)" v-else-if="isLoading || courses.pageNum === 0 || courses.total > courses.pageNum * courses.pageSize">加载中<span class="iconfont icon-likesprogramjiazaizhong icon-likesprogramjiazaizhongxuanz"></span></div>
            <div class="empty miniFont" v-else>没&nbsp;&nbsp;有&nbsp;&nbsp;更&nbsp;&nbsp;多&nbsp;&nbsp;数&nbsp;&nbsp;据&nbsp;&nbsp;了</div>
        </div>
    </div>
</template>

<script lang="ts">

import { inject, nextTick, onMounted, onUnmounted, ref } from 'vue';

import CourTypeLabelBox, { SelectTypeLabels } from '@/components/course/CourTypeLabelBox.vue';
import CourseCard from '@/components/course/CourseCard.vue';
import { courseApi, CourseShow } from '@/api/course/Course';
import { PageResult } from '@/components/Pagination.vue';

export default {
    name: 'CourseHomeView'
};
</script>

<script setup lang="ts">
    // 课程筛选的标签
    const typeLabelBox = ref<SelectTypeLabels>({
        courseName: '',
	    typeList: [],
	    labelList: [],
	    difficulty: null
    });

    // 搜索分词数据
    const searchParticiple = ref<string[]>(null);

    // 定义搜索函数
    const searchFunction = (input: string): void => {
        console.log('课程搜索：', input);
        typeLabelBox.value.courseName = input;
        getCourseList(typeLabelBox.value as SelectTypeLabels, true);
    };

    // 定义搜索提示函数
    const searchPromptFunction = (input: string): Array<Object> => {
        console.log('课程搜索提示：', input);
        return [{ title: '搜索提示', path: '/search' }, { title: '搜索提示', path: '/search' }];
    };

    // 注入父组件提供的函数
    const takeOverSearch = inject<(
        search: (input: string) => void, prompt: (input: string) => Array<Object>, placeholder: string | undefined
    ) => void>("takeOverSearch");
    // 释放搜索事件
    const releaseSearch = inject<() => void | undefined>("releaseSearch");
    
    // 加载图标Dom元素
    const loadingDom = ref(null);
    // 加载观察者实例
    let loadingObject = null;
    // 正在加载
    const isLoading = ref(false);

    onMounted(() => {
        // 接管搜索事件，若 searchFunction 为空，则代表禁用搜索， searchPromptFunction 为空，则代表禁用搜索提示
        takeOverSearch(searchFunction, searchPromptFunction, "搜索课程");
        // 等等Dom 加载完成
        nextTick(() => {
            loadingObject = new IntersectionObserver(async (entries)=>{
                for(let entry of entries) {
                    if (entry.isIntersecting) {
                        await getCourseList(typeLabelBox.value, false);
                    }
                }
            }, {
                root: null // 默认为当前视窗
                , threshold: 0.5 // 触发回调函数的阈值，当目标元素与根元素（视窗）的交叉比例超过这个值时，触发回调函数
            }); // 创建一个观察者实例
            loadingObject.observe(loadingDom.value);
        });
    });

    onUnmounted(() => {
        releaseSearch(); // 释放搜索事件
        if (loadingObject) {
            loadingObject.disconnect(); // 断开所有观察
        }
    });

    // 处理标签变化
    const updateData = (selectTypeLabels: SelectTypeLabels) => {
        typeLabelBox.value.typeList = selectTypeLabels.typeList;
        typeLabelBox.value.labelList = selectTypeLabels.labelList;
        typeLabelBox.value.difficulty = selectTypeLabels.difficulty
        getCourseList(typeLabelBox.value, true);
    };

    // 在 setup() 函数中添加模拟课程数据
    const courses = ref<PageResult<CourseShow>>({
        total: 0,
        pageNum: 0,
        pageSize: 20,
        list: []
    });

    const getCourseList = async (typeLabels: SelectTypeLabels, clear: boolean = false) => {
        if (isLoading.value) return;
        if (clear) courses.value.pageNum = 0;
        if(courses.value.pageNum !== 0 && courses.value.total <= courses.value.pageNum * courses.value.pageSize) return;
        isLoading.value = true; // 加载中
        if (loadingDom.value) loadingObject.unobserve(loadingDom.value); // 先取消观察
        courses.value.pageNum += 1;
        await courseApi.findCourse({
            courseName: typeLabels?.courseName, 
            courseType: typeLabels?.typeList, courseLabel: typeLabels?.labelList,
            courseDifficulty: typeLabels?.difficulty, pageNum: courses.value.pageNum, pageSize: courses.value.pageSize
        }).then(res => {
            // 添加数据 （合并两个list）
            if (clear) courses.value.list = [];
            courses.value.list = [...courses.value.list, ...res?.data.list];
            courses.value.total = res.data.total;
            courses.value.pageNum = res.data.pageNum;
            courses.value.pageSize = res.data.pageSize;
            searchParticiple.value = res.participle;
        }).finally(() => {
            // 等等Dom完成渲染
            nextTick(() => {
                // 等等 1 秒后，再观察 loadingDom
                setTimeout(() => {
                    if (isLoading) isLoading.value = false; // 加载完成
                    if (loadingDom.value) loadingObject.observe(loadingDom.value); // 再重新观察
                }, 1000);
            });
        });
    }

</script>

<style src="@/assets/icons/iconfont.css" scoped></style>

<style scoped>
.courseHomeView {
    width: var(--width);
    height: 100%;
    padding-top: 10px;
}
.filterSection {
    margin-bottom: 30px;
}

.dialog-footer {
    display: flex;
    justify-content: flex-end;
    gap: 12px;
    padding: 0 20px 20px;
}


.courseGrid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 30px 0px; /* 项目之间的间距 */
    justify-items: center;
    padding-bottom: 20px;
}

.pagination {
    display: flex;
    justify-content: center;
    margin-top: 32px;
}


.empty {
    font-size: 32px;
    font-weight: bold;
	font-family: "artisticFonts";
    display: flex;
    justify-content: center;
    align-items: center;
    padding-bottom: 20px;
    color: rgba(180, 180, 180, 1);
}
.empty.miniFont {
    font-size: 20px;
    color: rgba(140, 140, 140, 1);
}
.empty .iconfont {
    font-size: 26px;
    padding: 0px 5px;
}

</style>